﻿using RemoteDesktop.Compent;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Threading;

namespace RemoteDesktop
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private IntPtr CurrHandle = IntPtr.Zero;
        WindowPreview windowPreview = null;
        private TcpClient serverClient;
        PacketStream serverStream;
        private DispatcherTimer HeartTimer;
        private TcpListener ServerListerer;
        TcpClient tcpClient;
        PacketStream clientStream;
        bool ClientConnected;
        private int ServerPort = 8008;
        private bool isShareWindow;
        private Context context;
        private bool IsClosing = false;
        public bool IsAllScreen = false;
        private ImageSourceConverter Converter;
        private IntPtr hHook;
        LowLevelKeyboardProcDelegate hookProc; // prevent gc
        const int WH_KEYBOARD_LL = 13;
        IntPtr hModule;
        IntPtr hwnd; 
        public bool IsAddControl = false;

        public Toast mToastForm;
        //private System.Windows.Controls.Image Desktop;
        //private System.Windows.Controls.TextBox textBox;
        private NotifyIcon _notifyIcon = null;
        WindowCmd windowCmd = null;
        public WindowScreen pageScreen = null;
        public MainWindow()
        {
            InitializeComponent();
            InitConfig();
            Init();
            if (context.RoleType == "发送方")
            {
                InitialTray();
            }
            pageScreen = new WindowScreen();
            pageScreen.Show();
        }
        #region 最小化系统托盘
        private void InitialTray()
        {
            //隐藏主窗体
            this.Visibility = Visibility.Hidden;
            this.ShowInTaskbar = false;

            if (_notifyIcon == null)
            {
                //设置托盘的各个属性
                _notifyIcon = new NotifyIcon();
                _notifyIcon.BalloonTipText = "运行中...";//托盘气泡显示内容
                _notifyIcon.Text = "界面共享";
                _notifyIcon.Visible = true;//托盘按钮是否可见
                _notifyIcon.Icon = new Icon("img/favicon.ico"); //System.Drawing.Icon.ExtractAssociatedIcon(System.Windows.Forms.Application.ExecutablePath);
                //_notifyIcon.ShowBalloonTip(1000);//托盘气泡显示时间
                _notifyIcon.MouseDoubleClick += notifyIcon_MouseDoubleClick;
                //打开菜单项
                System.Windows.Forms.MenuItem open = new System.Windows.Forms.MenuItem("打开");
                open.Click += new EventHandler(Show);
                //打开菜单项
                System.Windows.Forms.MenuItem edit = new System.Windows.Forms.MenuItem("编辑");
                edit.Click += new EventHandler(Edit);
                //退出菜单项
                System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("退出");
                exit.Click += new EventHandler(Close);
                //关联托盘控件
                System.Windows.Forms.MenuItem[] childen = new System.Windows.Forms.MenuItem[] { open, edit, exit };
                _notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
            }
            else
            {
                _notifyIcon.ShowBalloonTip(1000);
            }
            this.WindowState = WindowState.Normal;

        }

        private void notifyIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            this.Visibility = Visibility.Visible;
            this.ShowInTaskbar = true;
            this.Activate();
        }
        private void Show(object sender, EventArgs e)
        {
            this.Visibility = System.Windows.Visibility.Visible;
            this.ShowInTaskbar = true;
            this.Activate();
        }
        private void Edit(object sender, EventArgs e)
        {
            pageScreen.ShowEditBox();
        }
        private void Close(object sender, EventArgs e)
        {
            //this.Close();
            Environment.Exit(0);
        }
        #endregion
        private void InitConfig()
        {
            context = Context.Get();
            string mIpAddress = PLogs.GetSettingString("ip_address");
            string sIpAddress1 = PLogs.GetSettingString("server_ip_address1");
            string mRoleType = PLogs.GetSettingString("role_type");
            string mIpAddressPort = PLogs.GetSettingString("ip_address_port");
            string sIpAddress1Port = PLogs.GetSettingString("server_ip_address1_port");
            string mIpAddressRole = PLogs.GetSettingString("ip_address_role");
            string sIpAddress1Role = PLogs.GetSettingString("server_ip_address1_role");
            if (mIpAddress != null)
            {
                context.IpAddress = mIpAddress;
            }
            if (sIpAddress1 != null)
            {
                context.ServerIpAddress1 = sIpAddress1;
            }
            if (mRoleType != null)
            {
                context.RoleType = mRoleType;
            }
            if (mIpAddressPort != null)
            {
                context.IpAddressPort = mIpAddressPort;
            }
            if (sIpAddress1Port != null)
            {
                context.ServerIpAddress1Port = sIpAddress1Port;
            }
            if (mIpAddressRole != null)
            {
                context.IpAddressRole = mIpAddressRole;
            }
            if (sIpAddress1Role != null)
            {
                context.ServerIpAddress1Role = sIpAddress1Role;
            }
            if (mIpAddress != "")
            {
                context.SetConnectInfo(mIpAddress, new ConnectInfo(mIpAddress, mIpAddressPort, mIpAddressRole));
            }
            if (sIpAddress1 != "")
            {
                context.SetConnectInfo(sIpAddress1, new ConnectInfo(sIpAddress1, sIpAddress1Port, sIpAddress1Role));
            }
        }

        private void Init()
        {
            Title = "界面共享";
            mToastForm = new Toast("", this);
            Converter = new ImageSourceConverter();

            HeartTimer = new DispatcherTimer();
            HeartTimer.Interval = TimeSpan.FromMilliseconds(50);
            HeartTimer.Tick += HeartTimer_Tick;
            HeartTimer.Start();
            if (context.IpAddressPort != null && context.IpAddressPort != "")
            {
                ServerPort = int.Parse(context.IpAddressPort);
            }
            if (context.RoleType == "发送方")
            {
                //ContentBox.Children.Remove(Desktop);
                Desktop.Visibility = Visibility.Collapsed;
                //textBox = new System.Windows.Controls.TextBox {
                //    Text = "客户端监听中...",
                //    TextAlignment = TextAlignment.Center,
                //    VerticalAlignment = VerticalAlignment.Top,
                //    HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
                //    Background = new SolidColorBrush(Colors.LightGray),
                //    Margin = new Thickness(0, 0, 0, 0)
                //};
                //Grid.SetRow(Desktop, 1);
                //Grid.SetColumn(Desktop, 0);
                //Contrianer.Children.Add(textBox);
                ConfugMenu.Visibility = Visibility.Visible;
                textBox.Visibility = Visibility.Visible;
                try
                {

                    ServerListerer = new TcpListener(IPAddress.Any, ServerPort);
                    ServerListerer.Start();

                    Thread thread = new Thread(ReciveAndListener);
                    thread.Start();
                }catch (Exception ex)
                {
                    PLogs.Error(ex.Message,ex.StackTrace);
                    System.Windows.MessageBox.Show(ex.Message);
                }

                CurrHandle = Desktopduplication.GetDesktopWindow();
            }
            else if(context.RoleType == "接收方")
            {
                //ContentBox.Children.Remove(textBox);
                textBox.Visibility= Visibility.Collapsed; 
                //Desktop = new System.Windows.Controls.Image { VerticalAlignment = VerticalAlignment.Top, Margin = new Thickness(0, 0, 0, 0), HorizontalAlignment = System.Windows.HorizontalAlignment.Left, Stretch = Stretch.Fill };
                //Grid.SetRow(Desktop, 1);
                //Grid.SetColumn(Desktop, 0);
                //Desktop.Source = new BitmapImage(new Uri("/rect.jpg", UriKind.Relative));
                //Contrianer.Children.Add(Desktop);
                FileMenu.Visibility = Visibility.Visible;
                ConfugMenu.Visibility = Visibility.Visible;
                Desktop.Visibility = Visibility.Visible;
                Thread thread = new Thread(ClientAndListener);
                thread.Start();
            }
            StatusText.Foreground = System.Windows.Media.Brushes.OrangeRed;

            MouseEnter += Desktop_MouseEnter;
            MouseLeave += Desktop_MouseLeave;
            hModule = GetModuleHandle(IntPtr.Zero);
            hookProc = new LowLevelKeyboardProcDelegate(LowLevelKeyboardProc);
            hwnd = new WindowInteropHelper(this).Handle;
        }
        private void HeartTimer_Tick(object sender, EventArgs e)
        {
            if (context.RoleType == "发送方")
            {
                ServerSend();
            }
            pageScreen.UpdateDateTime();
        }

        private void ServerSend()
        {
            if (serverClient != null && serverClient.Connected)
            {
                if (CurrHandle != IntPtr.Zero)
                {
                    long currentTimeMillis = DateTime.Now.Ticks / 10000;
                    if (currentTimeMillis - OldTime < 100)
                    {
                        return;
                    }
                    OldTime = currentTimeMillis;
                    try
                    {
                        //如果被锁就丢弃
                        if (Monitor.TryEnter(serverStream.tcpClient))
                        {

                            Bitmap bitmap = null;
                            if (windowPreview == null || windowPreview.Name == "桌面")
                            {
                                bitmap = Desktopduplication.TakeScreenshotWithCursor();
                            }
                            else
                            {
                                bitmap = Desktopduplication.CaptureWindow(CurrHandle);
                            }
                            // sendBitmap(bitmap, 's');
                            MemoryStream memoryStream = new MemoryStream();
                            bitmap.Save(memoryStream, ImageFormat.Jpeg);
                            byte[] sBytes = memoryStream.ToArray();
                            DataPakage pakage = new DataPakage(DataPakage.TYPE_SCREEN);
                            pakage.Data = sBytes;
                            serverStream.Send<DataPakage>(pakage);
                            //byte[] bt = context.Serialize(pakage);
                            //byte[] imageBytes = ImgUtils.Compress(bt);
                            //serverClient.GetStream().Write(imageBytes, 0, imageBytes.Length);
                            Monitor.Exit(serverStream.tcpClient);
                            //Thread.Sleep(20);
                        }
                        else
                        {
                            PLogs.Error("Screen", "Throw Packet");
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex.Message.Contains("句柄无效"))
                        {
                            windowPreview = new WindowPreview();
                            windowPreview.Name = "句柄无效";
                            CurrHandle = Desktopduplication.GetDesktopWindow();
                        }
                        else
                        {
                            UpdateLogs("窗口关闭或连接断开");
                            CurrHandle = Desktopduplication.GetDesktopWindow();
                            windowPreview = null;
                        }
                        PLogs.Error(ex.Message, ex.StackTrace);
                    }
                }
                try
                {
                    if (serverClient.GetStream().DataAvailable)
                    {
                        //byte[] byteArray = new byte[1024];
                        //int bytesRead = serverClient.GetStream().Read(byteArray, 0, byteArray.Length);
                        //if (bytesRead > 0)
                        //{
                        //    DataPakage pakage = context.Deserialize<DataPakage>(byteArray);
                        //    DoSomeThink(pakage);
                        //}
                        DataPakage pakage = serverStream.Recv<DataPakage>();
                        DoSomeThink(pakage);
                    }
                }
                catch (Exception ex)
                {
                    PLogs.Error(ex.Message, ex.StackTrace);
                    UpdateLogs(ex.Message);
                    if (ex.Message.Contains("不允许对非连接的套接字执行此操作"))
                    {
                        serverClient = null;
                        serverStream = null;
                    }
                }
            }
        }
        private void sendBitmap(Bitmap bitmap, Char cr)
        {
            bool isRole = false;
            if (serverClient == null)
            {
                return;
            }
            try
            {
                if (serverClient.Connected)
                {
                    MemoryStream memoryStream = new MemoryStream();
                    bitmap.Save(memoryStream, ImageFormat.Jpeg);
                    byte[] imageBytes = memoryStream.ToArray();
                    if (isRole)
                    {
                        byte[] bytesCamera = BitConverter.GetBytes(cr);
                        byte[] combinedBytes = new byte[imageBytes.Length + bytesCamera.Length];
                        Buffer.BlockCopy(bytesCamera, 0, combinedBytes, 0, 2);
                        Buffer.BlockCopy(imageBytes, 0, combinedBytes, 2, imageBytes.Length);
                        serverClient.GetStream().Write(combinedBytes, 0, combinedBytes.Length);
                    }
                    else
                    {
                        serverClient.GetStream().Write(imageBytes, 0, imageBytes.Length);
                    }
                }
            }
            catch (Exception ex)
            {
                tcpClient.Dispose();
                tcpClient.Close();
                tcpClient = null;
                PLogs.Error(ex.StackTrace.ToString(), ex.Message);
            }
        }

        private void ClientAndListener()
        {
            while (true)
            {
                if (tcpClient == null)
                {
                    if (context.ServerIpAddress1 != null && context.ServerIpAddress1 != "" && context.ServerIpAddress1Port != "")
                    {
                        try
                        {
                            int ServerIpAddress1Port = int.Parse(context.IpAddressPort);
                            tcpClient = new TcpClient();
                            UpdateLabel($"正在连接{context.ServerIpAddress1}");
                            tcpClient.Connect(context.ServerIpAddress1, ServerIpAddress1Port);
                            ClientConnected = true;
                            UpdateLabel($"已连接{context.ServerIpAddress1}");
                            clientStream = new PacketStream(tcpClient, false);
                        }
                        catch(Exception ex)
                        {
                            PLogs.Error("ClientAndListener", ex.Message);
                            ClientConnected = false;
                            tcpClient = null;
                            clientStream = null;
                            UpdateLabel($"{context.ServerIpAddress1}连接断开");
                        }
                    }
                    Thread.Sleep(1000);
                }
                else
                {
                    ClientRender();
                    Thread.Sleep(60);
                }
            }
           
        }
        private void ClientRender()
        {
            
            if (ClientConnected)
            {
                try
                {
                    // Receive image bytes from server
                    //byte[] imageBytes = new byte[1024 * 1024];
                    //int bytesRead = tcpClient.GetStream().Read(imageBytes, 0, imageBytes.Length);
                    //if (bytesRead > 1024)
                    //{
                    //    Render(imageBytes);
                    //}
                    DataPakage pakage = clientStream.Recv<DataPakage>();
                    if (pakage != null)
                    {
                        if (pakage.Type == DataPakage.TYPE_SCREEN)
                        {
                            ImageSource img = (ImageSource)Converter.ConvertFrom(pakage.Data);
                            Dispatcher.Invoke(new Action(() =>
                            {
                                Desktop.Source = img;
                            }));
                        }
                        else if (pakage.Type == DataPakage.TYPE_COMMAND_RESAULT)
                        {
                            if (windowCmd != null)
                            {
                                windowCmd.UpdateInfomation(pakage.Tag);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    PLogs.Error("ClientRender", ex.Message);
                    if (ex.Message.Contains("未找到适用于完成此操作的图像处理组件"))
                    {

                    }else if (ex.Message.Contains("输入流是无效的二进制格式"))
                    {
                        PLogs.Error("Message", ex.Message);
                    }
                    else
                    {
                        tcpClient.Dispose();
                        tcpClient.Close();
                        tcpClient = null;
                        ClientConnected = false;
                    }
                }
            }
        }
        private void Render(byte[] rBytes)
        {
            try
            {
                byte[] imageBytes = ImgUtils.Decompress(rBytes);
                DataPakage pakage = context.Deserialize<DataPakage>(imageBytes);
                if(pakage != null)
                {
                    if(pakage.Type == DataPakage.TYPE_SCREEN)
                    {
                        ImageSource img = (ImageSource)Converter.ConvertFrom(pakage.Data);
                        Dispatcher.Invoke(new Action(() =>
                        {
                            Desktop.Source = img;
                        }));
                    }else if (pakage.Type == DataPakage.TYPE_COMMAND_RESAULT)
                    {
                        if (windowCmd != null)
                        {
                            windowCmd.UpdateInfomation(pakage.Tag);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (e.Message.Contains("输入流是无效的二进制格式"))
                {
                    PLogs.Error("Message", e.Message);
                }
                else
                {
                    PLogs.Error(e.Message, e.StackTrace);
                }
            }
        }

        private void ReciveAndListener()
        {
            while (!IsClosing)
            {
                if(serverClient == null)
                {
                    UpdateLogs("等待连接...");
                    serverClient = ServerListerer.AcceptTcpClient();
                    serverStream = new PacketStream(serverClient, true);
                    string ip = serverClient.Client.RemoteEndPoint.ToString().Split(':')[0];
                    if (ip != "")
                    {
                        UpdateLogs($"{ip}已连接");
                    }
                }
                Thread.Sleep(1000);
            }
        }

        private void DoSomeThink(DataPakage pakage)
        {
            //UpdateLabel($"{arr[0]},{arr[1]},{arr[2]},{arr[3]}");
            if(pakage.Type == DataPakage.TYPE_MOUNSE)
            {
                int dpiX = (int)(Screen.PrimaryScreen.Bounds.Width * pakage.PX);
                int dpiY = (int)(Screen.PrimaryScreen.Bounds.Height * pakage.PY);
                if (pakage.Tag=="mousemove")
                {
                    //double screenWidth = SystemParameters.PrimaryScreenWidth;
                    //double screenHeight = SystemParameters.PrimaryScreenHeight;
                    Desktopduplication.SetCursorPos(dpiX, dpiY);
                }else if(pakage.Tag == "mouseleftdown")
                {
                    Desktopduplication.mouse_event(Desktopduplication.MOUSEEVENTF_LEFTDOWN, dpiX, dpiY, 0, 0);
                }
                else if (pakage.Tag == "mouseleftup")
                {
                    Desktopduplication.mouse_event(Desktopduplication.MOUSEEVENTF_LEFTUP, dpiX, dpiY, 0, 0);
                }
                else if (pakage.Tag == "mouserightdown")
                {
                    Desktopduplication.mouse_event(Desktopduplication.MOUSEEVENTF_RIGHTDOWN, dpiX, dpiY, 0, 0);
                }
                else if (pakage.Tag == "mouserightup")
                {
                    Desktopduplication.mouse_event(Desktopduplication.MOUSEEVENTF_RIGHTUP, dpiX, dpiY, 0, 0);
                }
                else if (pakage.Tag == "keydown")
                {
                    Desktopduplication.mouse_event(Desktopduplication.MOUSEEVENTF_RIGHTUP, dpiX, dpiY, 0, 0);
                }
                else if (pakage.Tag == "keyup")
                {
                    Desktopduplication.mouse_event(Desktopduplication.MOUSEEVENTF_RIGHTUP, dpiX, dpiY, 0, 0);
                }
            }else if(pakage.Type == DataPakage.TYPE_KEYBOARD)
            {
                byte code = (byte)KeyInterop.VirtualKeyFromKey(pakage.key);
                if (pakage.Tag == "keydown")
                {
                    Desktopduplication.keybd_event(code, 0, 0, 0);
                }
                else if (pakage.Tag == "keyup")
                {
                    Desktopduplication.keybd_event(code, 0, 2, 0);
                }
            }else if (pakage.Type == DataPakage.TYPE_COMMAND && pakage.Tag!="")
            {
                if(pakage.Tag.Equals("UnlockComputer"))
                {
                    MouseHook.UnlockComputer();
                }else if (pakage.PX == 100)
                {
                    pageScreen.SetTheWords(pakage.Tag);
                }
                else
                {
                    string resault = Desktopduplication.RunCmd(pakage.Tag);
                    try
                    {
                        if (serverClient != null && serverClient.Connected)
                        {
                            if (context.RoleType == "发送方")
                            {
                                //UpdateLogs($"cmd:{pakage.Tag}\n{resault}");
                                DataPakage mPk = new DataPakage(DataPakage.TYPE_COMMAND_RESAULT);
                                mPk.Tag = resault;
                                serverStream.Send<DataPakage>(mPk);
                                //byte[] rBytes = context.Serialize<DataPakage>(mPk);
                                //byte[] imageBytes = ImgUtils.Compress(rBytes);
                                //serverClient.GetStream().Write(imageBytes, 0, imageBytes.Length);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        PLogs.Error(ex.Message, ex.StackTrace);
                    }
                }
            }
        }

        private void UpdateLabel(string txt)
        {
            Dispatcher.Invoke(new Action(() =>
            {
                StatusText.Header = txt;
            }));
        }
        private void UpdateLogs(string txt)
        {
            Dispatcher.Invoke(new Action(() =>
            {
                textBox.Text += "\n"+txt;
                textBox.ScrollToEnd();
            }));
        }

        internal void ShareWindow(WindowPreview selectedItem)
        {
            windowPreview = selectedItem;
            CurrHandle = selectedItem.WindowHandle;
            if (isShareWindow)
            {
                return;
            }
            isShareWindow = true;
        }

        private void ShareView_Click(object sender, RoutedEventArgs e)
        {
            ShareWindow shareWindow = new ShareWindow(this);
            shareWindow.ShowDialog();
        }

        private void CancelShareView_Click(object sender, RoutedEventArgs e)
        {
            if (!isShareWindow)
            {
                return;
            }
            CurrHandle = IntPtr.Zero;
            isShareWindow = false;
        }

        private void ConfigView_Click(object sender, RoutedEventArgs e)
        {
            ConfigWindow cnfig = new ConfigWindow();
            cnfig.ShowDialog();
        }
        private void CutView_Click(object sender, RoutedEventArgs e)
        {
            IntPtr deskTop = Desktopduplication.GetDesktopWindow();
            Bitmap bitMap = Desktopduplication.CaptureWindow(deskTop);
            /*MemoryStream memoryStream = new MemoryStream();
            bitMap.Save(memoryStream, ImageFormat.Jpeg);
            byte[] sBytes = memoryStream.ToArray();
            PLogs.Info("sBytes", $"{sBytes.Length}");
            byte[] imageBytes = ImgUtils.Compress(sBytes);
            PLogs.Info("imageBytes", $"{imageBytes.Length}");*/
            string v = ImgUtils.CaptureImage("Capture", "桌面截图", bitMap);

        }
        public byte[] MergeBytes(params byte[][] arrays)
        {
            return arrays.SelectMany(a => a).ToArray();
        }
        private void HelpView_Click(object sender, RoutedEventArgs e)
        {
            /*byte[] bytes1 = BitConverter.GetBytes(1);
            byte[] bytes2 = BitConverter.GetBytes('y');
            byte[] mergedBytes = MergeBytes(bytes1, bytes2);
            Char str = BitConverter.ToChar(bytes2, 0);
            string Msg = $"str:{str},bytes2:{bytes2.Length},mergedBytes:{mergedBytes.Length}";
            MessageBox.Show(Msg);*/
            AboutUsWindow us = new AboutUsWindow();
            us.ShowDialog();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (context.RoleType == "发送方")
            {
                e.Cancel = true;  // 取消关闭窗体
                this.Hide();  // 隐藏窗体
            }
            else
            {
                IsClosing = true;
                if (HeartTimer != null)
                {
                    HeartTimer.Tick -= HeartTimer_Tick;
                    HeartTimer.Stop();
                    HeartTimer = null;
                }

                MouseEnter -= Desktop_MouseEnter;
                MouseLeave -= Desktop_MouseLeave;

                UnhookWindowsHookEx(hHook); // release keyboard hook
            }
        }

        private void QuitView_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (!IsAllScreen && Desktop!=null)
            {
                Desktop.Width = ActualWidth-16;
                Desktop.Height = ActualHeight-59;
            }
            if (textBox != null)
            {
                textBox.Width = ActualWidth - 12;
                textBox.Height = ActualHeight - 60;
            }
        }
        private void CmdEvent_Click(object sender, RoutedEventArgs e)
        {
            windowCmd = new WindowCmd(this);
            windowCmd.Show();
        }
        private void EnterFullScreen()
        {
            WindowState = WindowState.Maximized;
            WindowStyle = WindowStyle.None;
            Topmost = true;
        }
        // (可选) 添加退出全屏模式的代码
        private void ExitFullScreen()
        {
            WindowState = WindowState.Normal;
            WindowStyle = WindowStyle.SingleBorderWindow;
            Topmost = false;
        }

        private void ChangeSmallView_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Minimized;
            WindowStyle = WindowStyle.None;
        }

        private void ChangeBigView_Click(object sender, RoutedEventArgs e)
        {
            ToggleFullScreen();
        }
        internal void AddAndRomoveListener(bool isAdd)
        {
            if (isAdd)
            {
                //Desktop.MouseEnter += Desktop_MouseEnter;
                Desktop.MouseMove += Desktop_MouseMove;
                //Desktop.MouseLeave += Desktop_MouseLeave;
                Desktop.MouseLeftButtonDown += Desktop_MouseLeftButtonDown;
                Desktop.MouseLeftButtonUp += Desktop_MouseLeftButtonUp;
                Desktop.MouseRightButtonDown += Desktop_MouseRightButtonDown;
                Desktop.MouseRightButtonUp += Desktop_MouseRightButtonUp;
                KeyDown += Window_KeyDown;
                KeyUp += Window_KeyUp;
                mToastForm.setScreenControlText("解除控制");
            }
            else
            {
                //Desktop.MouseEnter -= Desktop_MouseEnter;
                Desktop.MouseMove -= Desktop_MouseMove;
                //Desktop.MouseLeave -= Desktop_MouseLeave;
                Desktop.MouseLeftButtonDown -= Desktop_MouseLeftButtonDown;
                Desktop.MouseLeftButtonUp -= Desktop_MouseLeftButtonUp;
                Desktop.MouseRightButtonDown -= Desktop_MouseRightButtonDown;
                Desktop.MouseRightButtonUp -= Desktop_MouseRightButtonUp;
                KeyDown -= Window_KeyDown;
                KeyUp -= Window_KeyUp;
                mToastForm.setScreenControlText("屏幕控制");
            }
        }
        private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (!IsAddControl)
            {
                return;
            }
            Key key = e.Key;
            GetKeyEvent(key, "keydown");
            e.Handled = true;
        }
        private void Window_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (!IsAddControl)
            {
                return;
            }
            Key key = e.Key;
            StatusText.Header = GetKeyEvent(key, "keyup");
            e.Handled = true;
        }
        private long OldTime = 0;
        private string GetPercent(System.Windows.Point p,string ev)
        {
            if (!IsAddControl)
            {
                return "";
            }
            long currentTimeMillis = DateTime.Now.Ticks / 10000;
            if (currentTimeMillis - OldTime < 50)
            {
                return "";
            }
            OldTime = currentTimeMillis;
            float pX = (float)(p.X / Desktop.ActualWidth);
            float pY = (float)(p.Y / Desktop.ActualHeight);
            if (pX < 0)
            {
                pX = 0;
            }
            if (pY < 0)
            {
                pY = 0;
            }
            try
            {
                if (tcpClient != null)
                {
                    string msg = $"{ev},{pX},{pY}";
                    if (context.RoleType == "接收方")
                    {
                        //StatusText.Header = msg;
                        DataPakage mPk = new DataPakage(DataPakage.TYPE_MOUNSE);
                        mPk.Tag = ev;
                        mPk.PX = pX;
                        mPk.PY = pY;
                        clientStream.Send<DataPakage>(mPk);
                        //byte[] imageBytes = context.Serialize<DataPakage>(mPk);
                        //tcpClient.GetStream().Write(imageBytes, 0, imageBytes.Length);
                    }
                }
            }
            catch(Exception ex)
            {
                PLogs.Error(ex.Message, ex.StackTrace);
            }
            return $"{pX},{pY}";
        }
        internal void sendCommand(string currentText, bool isScreenWord)
        {
            if(!string.IsNullOrEmpty(currentText))
            {
                try
                {
                    if (tcpClient != null)
                    {
                        if (context.RoleType == "接收方")
                        {
                            DataPakage mPk = new DataPakage(DataPakage.TYPE_COMMAND);
                            mPk.Tag = currentText;
                            if (isScreenWord)
                            {
                                mPk.PX = 100;
                            }
                            //byte[] imageBytes = context.Serialize<DataPakage>(mPk);
                            //tcpClient.GetStream().Write(imageBytes, 0, imageBytes.Length);
                            clientStream.Send<DataPakage>(mPk);
                        }
                    }
                }
                catch (Exception ex)
                {
                    PLogs.Error(ex.Message, ex.StackTrace);
                }
            }
        }
        private string GetKeyEvent(Key ky, string ev)
        {
            if (!IsAddControl)
            {
                return "";
            }
            try
            {
                if (tcpClient != null)
                {
                    int keyCode = KeyInterop.VirtualKeyFromKey(ky);
                    string msg = $"{ev},{ky},{keyCode},key,other";
                    if (context.RoleType == "接收方")
                    {
                        //StatusText.Header = msg;
                        DataPakage mPk = new DataPakage(DataPakage.TYPE_KEYBOARD);
                        mPk.Tag = ev;
                        mPk.key = ky;
                        //byte[] imageBytes = context.Serialize<DataPakage>(mPk);
                        //tcpClient.GetStream().Write(imageBytes, 0, imageBytes.Length);
                        clientStream.Send<DataPakage>(mPk);
                    }
                }
            }
            catch (Exception ex)
            {
                PLogs.Error(ex.Message, ex.StackTrace);
            }
            return ky.ToString();
        }
        private void Desktop_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            System.Windows.Point p = e.GetPosition(Desktop);
            GetPercent(p, "mousemove");
            //IntPtr handle = new WindowInteropHelper(this).Handle;
            //Desktopduplication.SetCapture(handle);
            //Desktop.Focusable = true;
            // 显式设置键盘焦点到当前窗口
            //Keyboard.Focus(Desktop);
            hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hModule, 0);
            if (hHook == IntPtr.Zero)
            {
                //StatusText.Header = "Failed to set hook, error = " + Marshal.GetLastWin32Error();
            }
        }

        private void Desktop_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            System.Windows.Point p = e.GetPosition(Desktop);
            GetPercent(p, "mousemove");
        }

        private void This_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            System.Windows.Point p = e.GetPosition(Desktop);
            if (IsAllScreen)
            {
                // 如果鼠标靠近顶部边缘，显示菜单
                if (p.Y < 5) // 10是一个阈值，可以根据需要调整
                {
                    //MainMenu.Visibility = Visibility.Visible;
                    //MainMenu.Height = 20;
                    //MenuHeight.Height = new GridLength(20);
                    mToastForm.Show();
                }
                else
                {
                    //MainMenu.Visibility = Visibility.Hidden;
                    //MenuHeight.Height = new GridLength(0);
                    //MainMenu.Height = 0;
                    mToastForm.Hide();
                }
            }
        }

        private void Desktop_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            System.Windows.Point p = e.GetPosition(Desktop);
            GetPercent(p, "mousemove");
            //Desktopduplication.ReleaseCapture();'
            //Desktop.Focusable = false;
            // 显式设置键盘焦点到当前窗口
            //Keyboard.ClearFocus();
            UnhookWindowsHookEx(hHook); // release keyboard hook
        }

        private void Desktop_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            System.Windows.Point p = e.GetPosition(Desktop);
            GetPercent(p, "mouseleftdown");
        }

        private void Desktop_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            System.Windows.Point p = e.GetPosition(Desktop);
            GetPercent(p, "mouseleftup");
        }

        private void Desktop_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            System.Windows.Point p = e.GetPosition(Desktop);
            GetPercent(p, "mouserightup");
        }

        private void Desktop_MouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            System.Windows.Point p = e.GetPosition(Desktop);
            GetPercent(p, "mouserightup");
        }
        
        private void ControlEvent_Click(object sender, RoutedEventArgs e)
        {
            IsAddControl = !IsAddControl;
            AddAndRomoveListener(IsAddControl);
        }

        // 声明Windows API函数
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMAXIMIZED = 3;
        private const int SW_SHOWNOACTIVATE = 4;
        private const int SW_SHOW = 5;
        private const int SW_MINIMIZE = 6;
        private const int SW_SHOWMINNOACTIVE = 7;
        private const int SW_SHOWNA = 8;
        private const int SW_RESTORE = 9;
        private const int SW_SHOWDEFAULT = 10;
        private const int SW_FORCEMINIMIZE = 11;
        private const int SW_MAX = 11;
        private const int SWP_SHOWWINDOW = 0x0040;

        private const string TaskbarWindowClass = "Shell_TrayWnd";

        public void ToggleFullScreen()
        {
            IntPtr taskbarWindowHandle = FindWindow(TaskbarWindowClass, null);
            if (WindowState == System.Windows.WindowState.Normal)
            {
                // 全屏
                WindowStyle = System.Windows.WindowStyle.None;
                ResizeMode = System.Windows.ResizeMode.NoResize;
                WindowState = WindowState.Maximized;
                //Topmost = true;
                Left = 0;
                Top = 0;
                Width = System.Windows.SystemParameters.PrimaryScreenWidth;
                Height = System.Windows.SystemParameters.PrimaryScreenHeight;
                ShowWindow(taskbarWindowHandle, SWP_SHOWWINDOW); // 隐藏任务栏
                ChangeSize.Header = "退出全屏";
                IsAllScreen = true;
                MenuHeight.Height = new GridLength(0);
                MainMenu.Height = 0;
                Desktop.MouseMove += This_MouseMove;
                mToastForm.setAllScreenText("退出全屏");
                Desktop.Width = ActualWidth;
                Desktop.Height = ActualHeight;
            }
            else
            {
                IsAllScreen = false;
                Desktop.MouseMove -= This_MouseMove;
                // 退出全屏
                WindowStyle = System.Windows.WindowStyle.SingleBorderWindow;
                ResizeMode = System.Windows.ResizeMode.CanResize;
                WindowState = WindowState.Normal;
                Topmost = false;
                Width = 320; // 设置为期望的宽度
                Height = 180; // 设置为期望的高度
                ShowWindow(taskbarWindowHandle, SW_SHOW); // 显示任务栏
                ChangeSize.Header = "全屏显示";
                MenuHeight.Height = new GridLength(20);
                MainMenu.Height = 20;
                MainMenu.Visibility = Visibility.Visible;
                mToastForm.setAllScreenText("全屏显示");
                mToastForm.Hide();
            }
        }
        private struct KBDLLHOOKSTRUCT
        {
            public int vkCode;
            int scanCode;
            public int flags;
            int time;
            int dwExtraInfo;
        }

        private delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);

        //禁用系统ctrl alt delete



        //其他组合按键钩子
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId);

        [DllImport("user32.dll")]
        private static extern bool UnhookWindowsHookEx(IntPtr hHook);


        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(IntPtr path); 
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        private bool isPbKey = true;
        private int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
        {
            //StatusText.Header = $"{nCode},{wParam},{lParam.vkCode},{lParam.flags}";
            if (isPbKey && IsAddControl)
            {
                Key key = KeyInterop.KeyFromVirtualKey(lParam.vkCode);
                if (wParam == 256)
                {
                    GetKeyEvent(key, "keydown");
                }
                else if(wParam == 257)
                {
                    GetKeyEvent(key, "keyup");
                }
                //SendMessage(hwnd, nCode, wParam, lParam.vkCode);
                return 1;
            }
            if (nCode >= 0)
                switch (wParam)
                {
                    case 256: // WM_KEYDOWN
                    case 257: // WM_KEYUP
                    case 260: // WM_SYSKEYDOWN
                    case 261: // M_SYSKEYUP
                        if (
                            (lParam.vkCode == 0x09 && lParam.flags == 32) || // Alt+Tab
                            (lParam.vkCode == 0x1b && lParam.flags == 32) || // Alt+Esc
                            (lParam.vkCode == 0x73 && lParam.flags == 32) || // Alt+F4
                            (lParam.vkCode == 0x20 && lParam.flags == 32) || // Alt+Space
                            (lParam.vkCode == 0x1b && lParam.flags == 0) || // Ctrl+Esc

                            (lParam.vkCode == 0x2e && (((lParam.flags & 32) == 32) && (lParam.flags & 0) == 0)) || // Ctrl+Alt+Delete
                            (lParam.vkCode == 0x5b && lParam.flags == 1) || // Left Windows Key 
                            (lParam.vkCode == 0x5c && lParam.flags == 1))    // Right Windows Key 
                        {
                            return 1;
                        }
                        break;
                }
            return CallNextHookEx(0, nCode, wParam, ref lParam);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
            if (!Directory.Exists("Capture"))
            {
                Directory.CreateDirectory("Capture");
            }
            Icon icon = System.Drawing.Icon.FromHandle(System.Windows.Forms.Cursor.Current.Handle);
            Bitmap cursorPic = icon.ToBitmap();
            cursorPic.Save("Capture/cursor.jpg", ImageFormat.Jpeg);
        }
    }
}
